using System;
using System.Xml;
using System.IO;

namespace XmlParser
{
	public class XmlParser : IXmlParser
	{
		#region DataElement
		private XmlDocument v_XmlDoc;
		private IXmlObject v_RootElement; 
		private string v_RootElementName = "";
		private string v_XmlFileName = "";
        private string v_nameSpace = "";
		#endregion DataElement
		#region Constructor
		/// <summary>
		/// Constructs an Object of XmlParser
		/// </summary>
		public XmlParser(string Namespapce)
        {
            this.v_nameSpace = Namespapce;
        }

		/// <summary>
		/// To Create an Object of an XmlParser Class
		/// </summary>
		/// <returns>
		/// Returns: Refrance to an interface of IXmlParser.
		/// The referance represents an instance of XmlParser Object
		/// </returns>
		//public static IXmlParser CreateInstance()
		//{
			//return new XmlParser();
		//}

		/// <summary>
		/// Loads an Exmle Document in a define Set of Classes. 
		/// You can walk through by using RootElement Property of the instance of this class.
		/// </summary>
		/// <param name="XmlFilePath">
		/// Full Path of the Xml File. 
		/// Only File Name if the file is placed on the root of Executable File.</param>
		/// <param name="RootNode">
		/// A string representing RootNode of Xml Document
		/// </param>
		public void XmlLoad(string XmlFileName, string XmlString)
		{
			try
			{
				this.v_XmlFileName = XmlFileName;
				this.v_XmlDoc = new XmlDocument();
				try
				{
					if(XmlString != "")
						this.v_XmlDoc.LoadXml(XmlString);
					else
						this.v_XmlDoc.Load(XmlFileName);
				}
				catch(Exception)
				{
					this.v_XmlDoc.Load(XmlFileName);
				}
				this.v_RootElementName = this.v_XmlDoc.DocumentElement.Name;
			}
			catch(Exception ex)
			{
				throw ex;
			}
		}
		public void XmlParse(string AssemblyFullName)
		{
			try
			{
				XmlNodeList NodeList = v_XmlDoc.GetElementsByTagName(this.RootElementName);
				foreach(XmlNode Node in NodeList)
				{
					if (Node.NodeType == XmlNodeType.Element)
					{
						try
						{
							v_RootElement = XmlObject.CreateInstance(this.RootElementName, AssemblyFullName, this.RootElementName, this.v_nameSpace);
							v_RootElement.ProcessNode(Node);
						}
						catch(Exception ex)
						{
							throw ex;
						}
					}
				}
			}
			catch(Exception ex)
			{
				throw ex;
			}
		}

		#endregion Constructor
		#region Processor
		/// <summary>
		/// Save the Document to an Xml File represented by RootElement
		/// Hint1: You can change Xml Document by using RootElement Property of the instance of this class.
		/// Hint2: Changed Values will be saved in the XmlDocument.
		/// </summary>
		/// <param name="Path"></param>
		/// <param name="IsRelative"></param>
		/// <param name="FileName"></param>
		/// <returns></returns>
		public string XmlSave(string path, bool IsRelative, string FileName)
		{//v_XmlFileName
			string XmlString = v_RootElement.ToXmlString();
			try
			{
                if (IsRelative == true)
                    path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory , path); 
				if(!(Utility.WriteFile(path, false, FileName, XmlString)))
					throw new Exception("Unable to save file.");
			}
			catch(Exception ex)
			{
				throw ex;
			}
			return XmlString;
		}
		#endregion Processor
		#region Attributes
		/// <summary>
		/// An instance of a XmlObject representing the root element of the Xml file.
		/// You can walk through by using this Property.
		/// </summary>
		public IXmlObject RootElement
		{
			get{return v_RootElement;}
		}
		public string RootElementName
		{
			get{return v_RootElementName;}
		}
		#endregion Attributes
	}
}
